#include "qhostfactory.h"

#include "host/qabstracthost.h"

#include "host/qformhost.h"
#include "host/qkeyboardhost.h"

#include "xmlobject.h"

QMap<QString,tagHostInfo*>* QHostFactory::m_meta_map;
QList<tagHostInfo*>*        QHostFactory::m_metas;

bool hostLessThan(tagHostInfo* info1, tagHostInfo *info2)
{
    return info1->m_show_index <info2->m_show_index;
}


QHostFactory::QHostFactory(const QString &name,
                           const QString &show_icon,
                           const QString &show_name,
                           const QString &show_group,
                           int show_index,
                           const QMetaObject *host)
{
    static bool s=false;
    if(!s)
    {
        m_meta_map=new QMap<QString,tagHostInfo*>();
        m_metas=new QList<tagHostInfo*>();
        s=true;
    }
    register_host(name,show_icon,show_name,show_group,show_index,host);
}

void QHostFactory::register_host(const QString &name,
                                 const QString &show_icon,
                                 const QString &show_name,
                                 const QString &show_group,
                                 int show_index,
                                 const QMetaObject *host)
{
    tagHostInfo *info=m_meta_map->value(name);
    if(info==NULL)
    {
        info=new tagHostInfo;
    }
    info->m_host_object=host;
    info->m_name=name;
    info->m_show_icon=show_icon;
    info->m_show_name=show_name;
    info->m_show_group=show_group;
    info->m_show_index=show_index;
    m_meta_map->insert(name,info);
    m_metas->append(info);
}

QAbstractHost* QHostFactory::create_host(const QString &name)
{
    QAbstractHost* host=NULL;
    if(name==FORM_TITLE)
    {
        host=new QFormHost;
        host->init();
        host->set_attribute(HOST_TYPE,FORM_TITLE);
    }
    else if(name==KEYBOARD_TITLE)
    {
        host=new QKeyBoardHost;
        host->init();
        host->set_attribute(HOST_TYPE,KEYBOARD_TITLE);
    }
    else
    {
        tagHostInfo *info=m_meta_map->value(name);
        if(info==NULL)
        {
            return NULL;
        }
        const QMetaObject* obj=info->m_host_object;

        if(obj!=NULL)
        {
            host=(QAbstractHost*)obj->newInstance();
            host->init();
            host->set_attribute(HOST_TYPE,name);
        }
    }

    return host;
}

QList<tagHostInfo*> QHostFactory::get_host_info()
{
    static bool s=false;
    if(!s)
    {
        sort();
        s=true;
    }
    return *m_metas;
}

QAbstractHost* QHostFactory::create_host(XMLObject *xml)
{
    if(xml==NULL)
    {
        return NULL;
    }

    QAbstractHost* ret=NULL;

    if(xml->get_title()==FORM_TITLE)
    {
        ret=new QFormHost;
        ret->init();
        ret->from_object(xml);
        ret->set_attribute(HOST_TYPE,FORM_TITLE);
    }
    else if(xml->get_title()==KEYBOARD_TITLE)
    {
        ret=new QKeyBoardHost;
        ret->init();
        ret->from_object(xml);
        ret->set_attribute(HOST_TYPE,KEYBOARD_TITLE);
        ((QKeyBoardHost*)ret)->connect_button();
    }
    else
    {
        ret=create_host(xml->get_property(HOST_TYPE));
        if(ret!=NULL)
        {
            ret->from_object(xml);
        }
    }
    return ret;
}

tagHostInfo* QHostFactory::get_host_info(const QString &name)
{
    return m_meta_map->value(name);
}

void QHostFactory::sort()
{
    qStableSort(m_metas->begin(), m_metas->end(),hostLessThan);
}
